#include <chrono>
#include <memory>
#include <string>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

using namespace std::chrono_literals;

class QosExamplePublisher : public rclcpp::Node
{
public:
    QosExamplePublisher()
        : Node("qos_example_publisher")
    {
        // 创建一个QoS配置文件
        rclcpp::QoS qos(10);
        qos.reliability(RMW_QOS_POLICY_RELIABILITY_RELIABLE);
        qos.durability(RMW_QOS_POLICY_DURABILITY_VOLATILE);
        qos.lifespan(10s);

        // 创建一个发布者，并使用QoS配置文件
        publisher_ = this->create_publisher<std_msgs::msg::String>("qos_example_topic", qos);

        // 创建一个定时器，用于定期发送消息
        timer_ = this->create_wall_timer(
            1s, std::bind(&QosExamplePublisher::timer_callback, this));
    }

private:
    void timer_callback()
    {
        auto message = std_msgs::msg::String();
        message.data = "Hello, world!";
        RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
        publisher_->publish(message);
    }

    rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
    rclcpp::TimerBase::SharedPtr timer_;
};

class QosExampleSubscriber : public rclcpp::Node
{
public:
    QosExampleSubscriber()
        : Node("qos_example_subscriber")
    {
        // 创建一个QoS配置文件
        rclcpp::QoS qos(10);
        qos.reliability(RMW_QOS_POLICY_RELIABILITY_RELIABLE);
        qos.durability(RMW_QOS_POLICY_DURABILITY_VOLATILE);
        qos.lifespan(10s);

        // 创建一个订阅者，并使用QoS配置文件
        subscription_ = this->create_subscription<std_msgs::msg::String>(
            "qos_example_topic", qos, std::bind(&QosExampleSubscriber::topic_callback, this, std::placeholders::_1));
    }

private:
    void topic_callback(const std_msgs::msg::String::SharedPtr message)
    {
        RCLCPP_INFO(this->get_logger(), "Received: '%s'", message->data.c_str());
    }

    rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};

int main(int argc, char *argv[])
{
    rclcpp::init(argc, argv);

    auto publisher = std::make_shared<QosExamplePublisher>();
    auto subscriber = std::make_shared<QosExampleSubscriber>();

    // rclcpp::spin(publisher);
    rclcpp::spin(subscriber);

    rclcpp::shutdown();
    return 0;
}